home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
archiver
/
unix
/
zip19p1.zoo
/
vms
/
vms.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-18
|
19KB
|
760 lines
/*************************************************************************
* *
* VMS portions copyright (C) 1992 Igor Mandrichenko. *
* Permission is granted to any individual or institution to use, copy, *
* or redistribute this software so long as all of the original files *
* are included unmodified, that it is not sold for profit, and that *
* this copyright notice is retained. *
* *
*************************************************************************/
/*
* vms.c (zip) by Igor Mandrichenko Version 2.1-1
*
* Revision history:
* ...
* 2.1-1 16-feb-1992 I.Mandrichenko
* Get file size from XABFHC and check bytes rest in file before
* reading.
* 2.1-2 2-mar-1992 I.Mandrichenko
* Make code more standard
* 2.2 21-jun-1992 I.Mandrichenko
* Free all allocated space, use more static storage.
* Use memcompress() from bits.c (deflation) for block compression.
* To revert to old compression method #define OLD_COMPRESS
*/
#ifdef VMS /* For VMS only ! */
#define OLD_COMPRESS /*To use old compression method define it.*/
#include <rms.h>
#include <descrip.h>
#include <syidef.h>
#ifndef VAXC
/* This definition may be missed */
struct XAB {
unsigned char xab$b_cod;
unsigned char xab$b_bln;
short int xabdef$$_fill_1;
char *xab$l_nxt;
};
#endif
#ifndef SYI$_VERSION
#define SYI$_VERSION 4096 /* VMS 5.4 definition */
#endif
#include "zip.h"
#define ERR(s) !((s)&1)
#define RET_ERROR 1
#define RET_SUCCESS 0
#define RET_EOF 0
#define Kbyte 1024
typedef struct XAB *xabptr;
/*
* Extra record format
* ===================
* signature (2 bytes) = 'I','M'
* size (2 bytes)
* block signature (4 bytes)
* flags (2 butes)
* uncomprssed size(2 bytes)
* reserved (4 bytes)
* data (size-12 bytes)
* ....
*/
/*
* Extra field signature and block signatures
*/
#define SIGNATURE "IM"
#define EXTBSL 4 /* Block signature length */
#define RESL 8
#define BC_MASK 07 /* 3 bits for compression type */
#define BC_STORED 0 /* Stored */
#define BC_00 1 /* 0byte -> 0bit compression */
#define BC_DEFL 2 /* Deflated */
struct extra_block
{ ush im_sig;
ush size;
ulg block_sig;
ush flags;
ush length;
ulg reserved;
uch body[1]; /* The actual size is unknown */
};
#define FABSIG "VFAB"
#define XALLSIG "VALL"
#define XFHCSIG "VFHC"
#define XDATSIG "VDAT"
#define XRDTSIG "VRDT"
#define XPROSIG "VPRO"
#define XKEYSIG "VKEY"
#define VERSIG "VMSV"
/*
* Block sizes
*/
#define FABL (cc$rms_fab.fab$b_bln)
#define RABL (cc$rms_rab.rab$b_bln)
#define XALLL (cc$rms_xaball.xab$b_bln)
#define XDATL (cc$rms_xabdat.xab$b_bln)
#define XFHCL (cc$rms_xabfhc.xab$b_bln)
#define XKEYL (cc$rms_xabkey.xab$b_bln)
#define XPROL (cc$rms_xabpro.xab$b_bln)
#define XRDTL (cc$rms_xabrdt.xab$b_bln)
#define XSUML (cc$rms_xabsum.xab$b_bln)
#define EXTHL (4+EXTBSL+RESL)
#define EXTL0 ((FABL + EXTHL)+ \
(XFHCL + EXTHL)+ \
(XPROL + EXTHL)+ \
(XDATL + EXTHL)+ \
(XRDTL + EXTHL))
#ifdef OLD_COMPRESS
#define PAD sizeof(uch)
#else
#define PAD 10*sizeof(ush) /* Two extra bytes for compr. header */
#endif
#define PAD0 (5*PAD) /* Reserve space for the case when
* compression failes */
static int _compress();
/***********************************
* Function get_vms_attributes *
***********************************/
static uch *_compress_block();
static int get_vms_version();
int get_vms_attributes(z)
struct zlist *z;
/*
* Get file VMS file attributes and store them into extent fields.
* Store VMS version also.
* On error leave z intact.
*/
{
int status;
uch *extra=(uch*)NULL, *scan;
extent extra_l;
static struct FAB fab;
static struct XABSUM xabsum;
static struct XABFHC xabfhc;
static struct XABDAT xabdat;
static struct XABPRO xabpro;
static struct XABRDT xabrdt;
xabptr x = (xabptr)NULL, xab_chain = (xabptr)NULL, last_xab = (xabptr)NULL;
int nk, na;
int i;
int rc=RET_ERROR;
char verbuf[80];
int verlen = 0;
/*
* Initialize RMS control blocks and link them
*/
fab = cc$rms_fab;
xabsum = cc$rms_xabsum;
xabdat = cc$rms_xabdat;
xabfhc = cc$rms_xabfhc;
xabpro = cc$rms_xabpro;
xabrdt = cc$rms_xabrdt;
fab.fab$l_xab = (char*)&xabsum;
/*
* Open the file and read summary information.
*/
fab.fab$b_fns = strlen(z->name);
fab.fab$l_fna = z->name;
status = sys$open(&fab);
if (ERR(status))
{
#ifdef DEBUG
printf("get_vms_attributes: sys$open for file %s:\n error status = %d\n",
z->name, status);
#endif
goto err_exit;
}
nk = xabsum.xab$b_nok;
na = xabsum.xab$b_noa;
#ifdef DEBUG
printf("%d keys, %d alls\n", nk, na);
#endif
/*
* Allocate XABKEY and XABALL blocks ind link them
*/
xabfhc.xab$l_nxt = (char*)&xabdat;
xabdat.xab$l_nxt = (char*)&xabpro;
xabpro.xab$l_nxt = (char*)&xabrdt;
xabrdt.xab$l_nxt = (char*)0L;
xab_chain = (xabptr)(&xabfhc);
last_xab = (xabptr)(&xabrdt);
#define INIT(ptr,size,init) \
if( (ptr = (uch*)malloc(size)) == NULL ) \
{ \
printf( "get_vms_attributes: Insufficient memory.\n" ); \
goto err_exit; \
} \
*(ptr) = (init);
/*
* Allocate and initialize all needed XABKEYs and XABALLs
*/
for (i = 0; i < nk; i++)
{
struct XABKEY *k;
INIT(k, XKEYL, cc$rms_xabkey);
k->xab$b_ref = i;
if (last_xab != 0L)
last_xab->xab$l_nxt = (char*)k;
last_xab = (xabptr)k;
}
for (i = 0; i < na; i++)
{
struct XABALL *a;
INIT(a, XALLL, cc$rms_xaball);
a->xab$b_aid = i;
if (last_xab != 0L)
last_xab->xab$l_nxt = (char*)a;
last_xab = (xabptr)a;
}
fab.fab$l_xab = (char*)xab_chain;
#ifdef DEBUG
printf("Dump of XAB chain before DISPLAY:\n");
for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
dump_rms_block(x);
#endif
/*
* Get information on the file structure etc.
*/
status = sys$display(&fab, 0, 0);
if (ERR(status))
{
#ifdef DEBUG
printf("get_vms_attributes: sys$display for file %s:\n error status = %d\n",
z->name, status);
#endif
goto err_exit;
}
#ifdef DEBUG
printf("\nDump of XAB chain after DISPLAY:\n");
for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
dump_rms_block(x);
#endif
fab.fab$l_xab = 0; /* Keep XABs */
status = sys$close(&fab);
if (ERR(status))
{
#ifdef DEBUG
printf("get_vms_attributes: sys$close for file %s:\n error status = %d\n",
z->name, status);
#endif
goto err_exit;
}
extra_l = EXTL0 + nk * (XKEYL + EXTHL) + na * (XALLL + EXTHL);
#ifndef OLD_COMPRESS
extra_l += PAD0 + (nk+na) * PAD;
#endif
if( verlen = get_vms_version(verbuf,sizeof(verbuf)) )
{ extra_l += verlen + EXTHL;
#ifndef OLD_COMPRESS
extra_l += PAD;
#endif
}
if ((scan = extra = (uch *) malloc(extra_l)) == (uch*)NULL)
{
#ifdef DEBUG
printf("get_vms_attributes: Insufficient memory to allocate extra buffer\n");
#endif
goto err_exit;
}
if( verlen > 0 )
scan = _compress_block(scan,verbuf, verlen, VERSIG);
/*
* Zero all unusable fields to improve compression